package 状态机.请假demo;

import 状态机.请假demo.entity.LeavePermit;
import 状态机.请假demo.event.Event;
import 状态机.请假demo.handler.StatusHandlerRegistry;
import 状态机.请假demo.handler.impl.Fail;
import 状态机.请假demo.handler.impl.Submitted;
import 状态机.请假demo.handler.impl.Success;
import 状态机.请假demo.handler.impl.annualleavespecifichandler.ceo.CEOAgreeAnnualLeavePermitStatusHandler;
import 状态机.请假demo.handler.impl.annualleavespecifichandler.ceo.CEODisAgreeAnnualLeavePermitStatusHandler;
import 状态机.请假demo.handler.impl.annualleavespecifichandler.ceo.CEONeedModifyAnnualLeavePermitStatusHandler;
import 状态机.请假demo.handler.impl.annualleavespecifichandler.ceo.CEOPermittingAnnualLeavePermitStatusHandler;
import 状态机.请假demo.handler.impl.annualleavespecifichandler.leader.LeaderAgreeAnnualLeavePermitStatusHandler;
import 状态机.请假demo.handler.impl.annualleavespecifichandler.leader.LeaderDisAgreeAnnualLeavePermitStatusHandler;
import 状态机.请假demo.handler.impl.annualleavespecifichandler.leader.LeaderNeedModifyAnnualLeavePermitStatusHandler;
import 状态机.请假demo.handler.impl.annualleavespecifichandler.leader.LeaderPermittingAnnualLeavePermitStatusHandler;
import 状态机.请假demo.leavepermit.LeavePermitType;
import 状态机.请假demo.machine.NotifySpecificLeavePermitHandler;
import 状态机.请假demo.machine.StatusMachineEngine;
import 状态机.请假demo.status.Status;

public class RunStatusMachineApp {

    public static void main(String[] args) {
        // 注册假条-流程-处理者
        registryAnnualPermitStatusHandler();


        // 注册EventBus订阅者
        NotifySpecificLeavePermitHandler notifySpecificLeavePermitHandler = new NotifySpecificLeavePermitHandler();
        StatusMachineEngine.addListener(notifySpecificLeavePermitHandler);

        // 创建假条
        LeavePermit leavePermit = new LeavePermit();
        leavePermit.setLeavePermitType(LeavePermitType.ANNUAL_LEAVE);
        leavePermit.setStatus(Status.PERMIT_SUBMIT);
        leavePermit.setUser("tqz");

        // 把假条交给引擎处理
        StatusMachineEngine.post(leavePermit);

        System.out.println("----- 分割线 代表假条需要领导审批了，这里模拟领导，给个通过意见,然后让状态机接着走-------");

        // 更改假条的 Event 之后，让引擎去处理即可
        leavePermit.setEvent(Event.AGREE);
        StatusMachineEngine.post(leavePermit);

        System.out.println("----- 分割线 代表假条需要ceo审批了，ceo给个通过意见,然后状态机接着走-------");

        // 更改假条的 Event 之后，让引擎去处理即可
        leavePermit.setEvent(Event.AGREE);
        StatusMachineEngine.post(leavePermit);

        System.out.println("--->>>>>>>>>end<<<<<<<<-------");
    }

    /**
     * 注册休假类型，以及处理该类型的流程是哪些，以及各个流程的处理者是谁
     * <p>
     * 这种做法就好比是写了一长串 if else
     * <p>
     * 每一个流程的具体处理者都继承了 StatusHandler 而该 StatusHandler 又是 AbstractStatusHandler 的子类
     * StatusHandler 实现了 AbstractStatusHandler 里面规定的 handle 方法
     * StatusHandler 自己又规定了一些其他的方法，例如让子类（具体处理者）去实现的 doHandler 方法，以及获取下一个状态的 after 方法
     */
    public static void registryAnnualPermitStatusHandler() {

        StatusHandlerRegistry.registryStatusHandler(LeavePermitType.ANNUAL_LEAVE, Status.PERMIT_SUBMIT, new Submitted());

        StatusHandlerRegistry.registryStatusHandler(LeavePermitType.ANNUAL_LEAVE, Status.LEADER_PERMIT_AGREE, new LeaderAgreeAnnualLeavePermitStatusHandler());
        StatusHandlerRegistry.registryStatusHandler(LeavePermitType.ANNUAL_LEAVE, Status.LEADER_PERMIT_DISAGREE, new LeaderDisAgreeAnnualLeavePermitStatusHandler());
        StatusHandlerRegistry.registryStatusHandler(LeavePermitType.ANNUAL_LEAVE, Status.LEADER_PERMIT_MODIFY, new LeaderNeedModifyAnnualLeavePermitStatusHandler());
        StatusHandlerRegistry.registryStatusHandler(LeavePermitType.ANNUAL_LEAVE, Status.LEADER_PERMITTING, new LeaderPermittingAnnualLeavePermitStatusHandler());

        StatusHandlerRegistry.registryStatusHandler(LeavePermitType.ANNUAL_LEAVE, Status.CEO_PERMIT_AGREE, new CEOAgreeAnnualLeavePermitStatusHandler());
        StatusHandlerRegistry.registryStatusHandler(LeavePermitType.ANNUAL_LEAVE, Status.CEO_PERMIT_DISAGREE, new CEODisAgreeAnnualLeavePermitStatusHandler());
        StatusHandlerRegistry.registryStatusHandler(LeavePermitType.ANNUAL_LEAVE, Status.CEO_PERMIT_MODIFY, new CEONeedModifyAnnualLeavePermitStatusHandler());
        StatusHandlerRegistry.registryStatusHandler(LeavePermitType.ANNUAL_LEAVE, Status.CEO_PERMITING, new CEOPermittingAnnualLeavePermitStatusHandler());

        StatusHandlerRegistry.registryStatusHandler(LeavePermitType.ANNUAL_LEAVE, Status.PERMIT_SUCCESS, new Success());
        StatusHandlerRegistry.registryStatusHandler(LeavePermitType.ANNUAL_LEAVE, Status.PERMIT_FAIL, new Fail());
    }
}
